﻿using Sidvall.Serialization;
using System.Collections.Generic;

namespace Sidvall.Web
{
    public class RouteTemplateSettings
    {
        #region Public Members

        public string RootPath { get; set; }

        #region ResourceMappings

        private ItemMappingCollection _ResourceMappings;
        public ItemMappingCollection ResourceMappings
        {
            get
            {
                if (_ResourceMappings == null)
                    _ResourceMappings = new ItemMappingCollection();
                return _ResourceMappings;
            }
        }

        #endregion
        #region ActionMappings

        private ItemMappingCollection _ActionMappings;
        public ItemMappingCollection ActionMappings
        {
            get
            {
                if (_ActionMappings == null)
                    _ActionMappings = new ItemMappingCollection();
                return _ActionMappings;
            }
        }

        #endregion

        #region GetResourceActionItem

        public ResourceActionItem GetResourceActionItem(string path)
        {
            bool isFileSystem;

            if (string.IsNullOrWhiteSpace(path))
                return null;

            if (path.Contains("/NetFileSystem/{StoreId}/", System.StringComparison.OrdinalIgnoreCase))
                isFileSystem = true;
            else
                isFileSystem = false;
            var parts = path.Split('/');
            var items = new List<string>();
            foreach (var part in parts)
            {
                var item = part.Trim();
                switch (item.ToUpperInvariant())
                {
                    case "API":
                    case "V1":
                    case "V2":
                    case "V3":
                    case "V4":
                    case "V5":
                    case "V6":
                    case "V7":
                    case "V8":
                    case "V9":
                        break;
                    case "NETFILESYSTEM":
                        if (!isFileSystem)
                            items.Add(item);
                        break;
                    default:
                        if (!item.StartsWith("{"))
                            items.Add(item);
                        break;
                }
            }
            if (items.Count < 2)
                return null;

            var resource = items[0];
            var action = items[1];

            if (isFileSystem)
            {
                var actions = new List<string>();
                var operation = action.ToNullableEnum<Sidvall.IO.FileSystemOperation>();
                switch (operation.Value)
                {
                    case IO.FileSystemOperation.Copy:
                        actions.Add(Sidvall.Security.Operations.GetItems);
                        actions.Add(Sidvall.Security.Operations.SaveItems);
                        break;
                    case IO.FileSystemOperation.Create:
                        actions.Add(Sidvall.Security.Operations.AddItems);
                        break;
                    case IO.FileSystemOperation.Delete:
                        actions.Add(Sidvall.Security.Operations.DeleteItems);
                        break;
                    case IO.FileSystemOperation.Exists:
                        actions.Add(Sidvall.Security.Operations.GetItemsMetadata);
                        break;
                    case IO.FileSystemOperation.Flush:
                        actions.Add(Sidvall.Security.Operations.SaveItems);
                        break;
                    case IO.FileSystemOperation.GetItem:
                        actions.Add(Sidvall.Security.Operations.GetItemsMetadata);
                        break;
                    case IO.FileSystemOperation.GetItems:
                        actions.Add(Sidvall.Security.Operations.GetItemsMetadata);
                        break;
                    case IO.FileSystemOperation.GetNames:
                        actions.Add(Sidvall.Security.Operations.GetItemsMetadata);
                        break;
                    case IO.FileSystemOperation.GetSize:
                        actions.Add(Sidvall.Security.Operations.GetItemsMetadata);
                        break;
                    case IO.FileSystemOperation.Move:
                        actions.Add(Sidvall.Security.Operations.SaveItems);
                        break;
                    case IO.FileSystemOperation.Read:
                        actions.Add(Sidvall.Security.Operations.GetItems);
                        break;
                    case IO.FileSystemOperation.WriteBuffer:
                        actions.Add(Sidvall.Security.Operations.SaveItems);
                        break;
                    case IO.FileSystemOperation.WriteStream:
                        actions.Add(Sidvall.Security.Operations.SaveItems);
                        break;
                    default:
                        break;
                }
                return new ResourceActionItem()
                {
                    Resources = this.ResourceMappings.GetItems(resource),
                    Actions = actions,
                };
            }
            else
            {
                return new ResourceActionItem()
                {
                    Resources = this.ResourceMappings.GetItems(resource),
                    Actions = this.ActionMappings.GetItems(action),
                };
            }
        }

        #endregion

        #endregion
        #region Factory Members

        #region GetDefaultSettings

        public static RouteTemplateSettings GetDefaultSettings(bool useDefaultMappings)
        {
            var item = new RouteTemplateSettings();
            if (useDefaultMappings)
            {
                item.ActionMappings.Add("GetItem", Sidvall.Security.Operations.GetItems);
                item.ActionMappings.Add("GetItemCount", Sidvall.Security.Operations.GetItemsMetadata);
                item.ActionMappings.Add("NewItem", Sidvall.Security.Operations.NewItems);
                item.ActionMappings.Add("SaveItem", Sidvall.Security.Operations.AddItems, Sidvall.Security.Operations.UpdateItems, Sidvall.Security.Operations.DeleteItems);
                item.ActionMappings.Add("UpdateItemsValues", Sidvall.Security.Operations.UpdateItemValues);
            }
            return item;
        }

        #endregion

        #endregion
    }
}
